import poplib
import email
from email.parser import Parser
from email.header import decode_header
import csv
import re
import os
from datetime import datetime


def decode_str(s):
    """解码邮件主题或发件人等字段"""
    if s is None:
        return ""

    result = ""
    parts = decode_header(s)

    for content, charset in parts:
        if isinstance(content, bytes):
            if charset:
                try:
                    result += content.decode(charset)
                except:
                    result += content.decode("utf-8", errors="replace")
            else:
                try:
                    result += content.decode()
                except:
                    result += content.decode("utf-8", errors="replace")
        else:
            result += str(content)

    return result


def get_email_content(msg):
    """获取邮件内容"""
    content = ""

    if msg.is_multipart():
        # 如果邮件有多个部分
        for part in msg.walk():
            content_type = part.get_content_type()
            content_disposition = str(part.get("Content-Disposition"))

            # 跳过附件
            if "attachment" in content_disposition:
                continue

            if content_type == "text/plain":
                try:
                    payload = part.get_payload(decode=True)
                    charset = part.get_content_charset()
                    if charset:
                        content = payload.decode(charset)
                    else:
                        content = payload.decode("utf-8", errors="replace")
                    break  # 找到文本内容后退出循环
                except Exception as e:
                    print(f"解码邮件内容时出错: {e}")
    else:
        # 如果邮件只有一个部分
        try:
            payload = msg.get_payload(decode=True)
            charset = msg.get_content_charset()
            if charset:
                content = payload.decode(charset)
            else:
                content = payload.decode("utf-8", errors="replace")
        except Exception as e:
            print(f"解码邮件内容时出错: {e}")

    return content


def is_related_to_target(msg, target_email):
    """检查邮件是否与目标邮箱有关"""
    from_addr = msg.get("From", "")
    to_addr = msg.get("To", "")
    cc_addr = msg.get("Cc", "") or ""

    # 检查发件人、收件人和抄送是否包含目标邮箱
    return (
        target_email.lower() in from_addr.lower()
        or target_email.lower() in to_addr.lower()
        or target_email.lower() in cc_addr.lower()
    )


def get_emails_to_csv(
    target_email,
    csv_filename,
):
    # 网易邮箱配置
    POP3_SERVER = "pop.163.com"
    POP3_PORT = 995
    EMAIL = "justforted@163.com"  # 你的网易邮箱地址

    # 使用网易邮箱的授权码
    AUTH_CODE = "HLykuQC6dsZVb7js"
    TARGET_EMAIL = target_email

    try:
        # 连接到POP3服务器
        print(f"正在连接到 {POP3_SERVER}...")
        pop_conn = poplib.POP3_SSL(POP3_SERVER, POP3_PORT)
        print("连接成功")

        # 登录
        print("正在登录...")
        pop_conn.user(EMAIL)
        pop_conn.pass_(AUTH_CODE)
        print("登录成功")

        # 获取邮件数量和大小
        message_count, mailbox_size = pop_conn.stat()
        print(
            f"邮箱中共有 {message_count} 封邮件，总大小约 {mailbox_size/1024/1024:.2f} MB"
        )

        # 准备CSV文件

        related_emails = []

        print(f"开始检索与 {TARGET_EMAIL} 相关的邮件...")

        # 获取所有邮件并检查是否与目标邮箱相关
        for i in range(1, message_count + 1):
            print(f"正在处理第 {i}/{message_count} 封邮件...", end="\r")

            try:
                # 获取邮件
                response, lines, octets = pop_conn.retr(i)

                # 解析邮件内容
                message_content = b"\r\n".join(lines)
                msg = email.message_from_bytes(message_content)

                # 检查是否与目标邮箱相关
                if is_related_to_target(msg, TARGET_EMAIL):
                    # 提取邮件信息
                    subject = decode_str(msg.get("Subject", ""))
                    from_addr = decode_str(msg.get("From", ""))
                    to_addr = decode_str(msg.get("To", ""))
                    date = msg.get("Date", "")

                    # 获取邮件内容
                    body = get_email_content(msg)

                    # 添加到相关邮件列表
                    related_emails.append(
                        {
                            "日期": date,
                            "发件人": from_addr,
                            "收件人": to_addr,
                            "主题": subject,
                            "内容": body,
                        }
                    )
                    print(f"\n找到相关邮件: {subject}")
            except Exception as e:
                print(f"\n处理第 {i} 封邮件时出错: {e}")

        print(f"\n找到 {len(related_emails)} 封与 {TARGET_EMAIL} 相关的邮件")

        # 将相关邮件写入CSV文件
        if related_emails:
            with open(csv_filename, "w", newline="", encoding="utf-8") as csvfile:
                fieldnames = ["日期", "发件人", "收件人", "主题", "内容"]
                writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
                writer.writeheader()

                for email_data in related_emails:
                    # 截断过长的内容
                    if len(email_data["内容"]) > 10000:
                        email_data["内容"] = (
                            email_data["内容"][:10000] + "...(内容已截断)"
                        )

                    writer.writerow(email_data)

            print(f"邮件已成功导出到 {csv_filename}")
        else:
            print(f"未找到与 {TARGET_EMAIL} 相关的邮件")

        # 关闭连接
        pop_conn.quit()
        print("已关闭连接")

    except Exception as e:
        print(f"发生错误: {e}")
        import traceback

        traceback.print_exc()


if __name__ == "__main__":
    source_email = "contact@alphaxiv.org"
    # source_email = "noreply@medium.com"
    # csv_filename = f"emails_with_{source_email.replace('@', '_at_')}_{datetime.now().strftime('%Y%m%d_%H%M%S')}.csv"
    csv_file = f"/data_ext/wxauto/proc_email/data/{source_email}.csv"
    get_emails_to_csv(source_email, csv_filename=csv_file)
